home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus Special 16 / AMIGAplus Sonderheft 16 (1998)(ICP)(DE)[!].iso / pd / anwendungen / xpk_source / libraries / rlen / xpkrlen.c < prev   
C/C++ Source or Header  |  1998-08-27  |  3KB  |  131 lines

  1. #include <xpk/xpksub.h>
  2.  
  3. #ifdef __MAXON__
  4.   #define __asm
  5. #endif
  6.  
  7. struct XpkMode RlenMode =
  8. {
  9.   NULL,                /* next            */
  10.   100,                /* upto            */
  11.   XPKMF_A3000SPEED,        /* flags        */
  12.   0,                /* packmem        */
  13.   0,                /* unpackmem        */
  14.   140,                /* packspeed, K / sec    */
  15.   1043,                /* unpackspeed, K / sec    */
  16.   45,                /* ratio, *0.1 %    */
  17.   0,                /* reserved        */
  18.   "normal"            /* description        */
  19. };
  20.  
  21. static struct XpkInfo RlenInfo =
  22. {
  23.   1,                /* info version */
  24.   1,                /* lib  version */
  25.   0,                /* master vers  */
  26.   0,                /* pad          */
  27.   "RLEN",            /* short name   */
  28.   "Run Length",            /* long name    */
  29.   "Fast and simple compression usable for simple data",    /* description*/
  30.   0x524C454E,            /* 4 letter ID  */
  31.   XPKIF_PK_CHUNK |        /* flags        */
  32.   XPKIF_UP_CHUNK,
  33.   0x7fffffff,            /* max in chunk */
  34.   0,                /* min in chunk */
  35.   0x4004,            /* def in chunk */
  36.   NULL,                /* pk message   */
  37.   NULL,                /* up message   */
  38.   NULL,                /* pk past msg  */
  39.   NULL,                /* up past msg  */
  40.   50,                /* def mode     */
  41.   0,                /* pad          */
  42.   &RlenMode            /* modes        */
  43. };
  44.  
  45. /*
  46.  * Returns an info structure about our packer
  47.  */
  48.  
  49. #ifdef __cplusplus
  50.   extern "C"
  51. #endif
  52.  
  53. struct XpkInfo * __asm XpksPackerInfo(void)
  54. {
  55.   return &RlenInfo;
  56. }
  57.  
  58. /*
  59.  * Pack a chunk
  60.  */
  61.  
  62. #ifdef __cplusplus
  63.   extern "C"
  64. #endif
  65.  
  66. LONG __asm XpksPackChunk(register __a0 struct XpkSubParams *xpar)
  67. {
  68.   UBYTE *get = xpar->xsp_InBuf, *start = xpar->xsp_InBuf;
  69.   UBYTE *end = get + xpar->xsp_InLen, *put = xpar->xsp_OutBuf;
  70.   UBYTE *wend = put + xpar->xsp_OutBufLen;
  71.   LONG run, i;
  72.  
  73.   for(;;)
  74.   {
  75.     run = get[0] == get[1] && get[1] == get[2];
  76.  
  77.     if(put + (get - start) + 4 > wend)
  78.       return XPKERR_EXPANSION;
  79.  
  80.     if(run || get - start == 127 || get == end)
  81.     {    /* write uncompressed */
  82.       if(get - start)
  83.       {
  84.     *put++ = get - start;
  85.     for(i = get - start; i > 0; i--)
  86.       *put++ = *start++;
  87.       }
  88.       if(get == end)
  89.       {
  90.     *put++ = 0;
  91.     break;
  92.       }
  93.       start = get;
  94.     }
  95.  
  96.     if(run)
  97.     {            /* write compressed   */
  98.       for(i = 3; get + i < end && get[i - 1] == get[i] && i < 127; i++);
  99.       *put++ = -i;
  100.       *put++ = get[0];
  101.       get += i;
  102.       start = get;
  103.     }
  104.     else
  105.       get++;
  106.   }
  107.   xpar->xsp_OutLen = put - (UBYTE *) xpar->xsp_OutBuf;
  108.  
  109.   return 0;
  110. }
  111.  
  112. #ifdef __cplusplus
  113.   extern "C"
  114. #endif
  115.  
  116. LONG __asm XpksUnpackChunk(register __a0 struct XpkSubParams *xpar)
  117. {
  118.   UBYTE *get = xpar->xsp_InBuf, *put = xpar->xsp_OutBuf, v;
  119.   LONG i;
  120.  
  121.   while(i = (BYTE) *get++)
  122.     if(i > 0)
  123.       for(; i > 0; i--)
  124.     *put++ = *get++;
  125.     else
  126.       for(i = -i, v = *get++; i > 0; i--)
  127.     *put++ = v;
  128.  
  129.   return 0;
  130. }
  131.